BT-09: Monitor Daemon & CLI
Goal: Implement the real-time monitoring daemon that ties collectors, correlator, and alerting together, plus CLI commands for monitoring operations.
Files:
- Create: /opt/security-blue-team/blueteam/monitor.py
- Modify: /opt/security-blue-team/blueteam/cli.py β add monitor commands
Depends on: BT-08
Step 1: Implement monitoring daemon
# blueteam/monitor.py
"""Real-time security monitoring daemon."""
import time
import signal
import sys
from datetime import datetime, timezone
from rich.console import Console
from rich.live import Live
from rich.table import Table
from blueteam.config import load_config
from blueteam.collectors import get_enabled_collectors
from blueteam.correlator.engine import CorrelationEngine
from blueteam.correlator.rules import ALL_RULES
from blueteam.alerting.engine import AlertEngine
console = Console()
class MonitorDaemon:
"""Main monitoring loop: collect β correlate β alert."""
def __init__(self, config: dict):
self.config = config
self.running = False
self.poll_interval = config.get("monitoring", {}).get("poll_interval_sec", 5)
# Initialize subsystems
self.collectors = get_enabled_collectors(config)
self.correlator = CorrelationEngine(config)
self.alert_engine = AlertEngine(config)
# Register all correlation rules with config overrides
rule_config = config.get("correlation", {}).get("rules", {})
for rule_cls in ALL_RULES:
kwargs = rule_config.get(rule_cls.name if hasattr(rule_cls, 'name') else '', {})
try:
rule = rule_cls(**kwargs) if kwargs else rule_cls()
self.correlator.register_rule(rule)
except TypeError:
self.correlator.register_rule(rule_cls())
# Stats
self.stats = {
"events_collected": 0,
"incidents_detected": 0,
"alerts_sent": 0,
"started_at": None,
"last_poll": None,
}
def start(self):
"""Start the monitoring loop."""
self.running = True
self.stats["started_at"] = datetime.now(timezone.utc)
signal.signal(signal.SIGINT, self._shutdown)
signal.signal(signal.SIGTERM, self._shutdown)
console.print(f"[bold green]Blue Team Monitor Started[/bold green]")
console.print(f" Collectors: {len(self.collectors)} enabled")
console.print(f" Rules: {len(self.correlator.rules)} active")
console.print(f" Poll interval: {self.poll_interval}s")
console.print(f" Press Ctrl+C to stop\n")
while self.running:
try:
self._poll_cycle()
time.sleep(self.poll_interval)
except KeyboardInterrupt:
break
console.print("\n[bold yellow]Monitor stopped.[/bold yellow]")
self._print_stats()
def _poll_cycle(self):
"""Single poll cycle: collect from all sources, correlate, alert."""
all_events = []
for collector in self.collectors:
try:
events = collector.collect()
all_events.extend(events)
except Exception as e:
console.print(f"[red]Collector {collector.name} error: {e}[/red]")
self.stats["events_collected"] += len(all_events)
self.stats["last_poll"] = datetime.now(timezone.utc)
if all_events:
incidents = self.correlator.process(all_events)
for incident in incidents:
self.stats["incidents_detected"] += 1
self.alert_engine.alert(incident)
self.stats["alerts_sent"] += 1
def _shutdown(self, signum, frame):
self.running = False
def _print_stats(self):
uptime = datetime.now(timezone.utc) - self.stats["started_at"]
console.print(f"\n[bold]Session Summary:[/bold]")
console.print(f" Uptime: {uptime}")
console.print(f" Events collected: {self.stats['events_collected']}")
console.print(f" Incidents detected: {self.stats['incidents_detected']}")
console.print(f" Alerts sent: {self.stats['alerts_sent']}")
Step 2: Wire up CLI commands
Add to blueteam/cli.py:
@main.command()
@click.pass_context
def monitor(ctx):
"""Start real-time security monitoring daemon."""
from blueteam.monitor import MonitorDaemon
daemon = MonitorDaemon(ctx.obj["config"])
daemon.start()
Step 3: Test the daemon
cd /opt/security-blue-team
source venv/bin/activate
blueteam monitor
# Should show: "Blue Team Monitor Started" with collector/rule counts
# Ctrl+C to stop, should show session summary
Step 4: Commit
git add -A
git commit -m "feat: real-time monitoring daemon (NIST 3.14.6, 3.14.7)"